<?php

namespace app\controller;

use app\BaseController;
use think\facade\Db;
use think\facade\Config;
use think\Response;
use think\facade\View;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use think\facade\Cache;

class Car extends BaseController
{
    private $lastError = ''; // 用于存储最后一个错误信息

    /**
     * 显示车辆二维码生成页面
     */
    public function qrcodePage()
    {

        $search = $this->request->param('search', '');
        $page = $this->request->param('page', 1, 'intval');
        $limit = 15; // 每页显示15条

        $query = Db::name('sysidcardinfo');

        if (!empty($search)) {
            // 仅搜索车牌号
            $query->where('CarNomber|IDCardNomber', 'like', '%' . $search . '%');
        }

        $list = $query->order('id', 'desc')->paginate([
            'list_rows' => $limit,
            'page' => $page,
        ]);

        return View::fetch('qrcode', [
            'carList' => $list->items(),
            'page' => $list->render(), // 使用框架自带的分页渲染
            'search' => $search
        ]);
    }

    /**
     * 获取车辆信息
     */
    public function getCarInfo()
    {
        $carNumber = $this->request->param('car_number', '');

        if (empty($carNumber)) {
            return json(['code' => 400, 'msg' => '车牌号不能为空']);
        }

        try {

            // 获取关联的卡信息
            $cardInfo = Db::name('sysidcardinfo')
                ->where('IDCardNomber|CarNomber', $carNumber)
                ->find();

            // 获取车辆基本信息
            $carInfo = Db::name('syscarinfo')
                ->where('CarNumber', $cardInfo['CarNomber'])
                ->find();

            if (!$carInfo || $cardInfo['CarNomber']!=$carInfo['CarNumber']) {
                return json(['code' => 404, 'msg' => '车辆ID卡绑定异常']);
            }

            $result = [
                'car_info' => $carInfo,
                'card_info' => $cardInfo
            ];

            return json(['code' => 200, 'data' => $result, 'msg' => '获取成功']);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }

    /**
     * 获取车辆列表（用于管理后台）
     */
    public function getCarList()
    {
        $page = $this->request->param('page', 1);
        $limit = $this->request->param('limit', 20);
        $status = $this->request->param('status', '');

        try {
            $query = Db::name('syscarinfo');

            if (!empty($status)) {
                $query->where('CarStatus', $status);
            }

            $list = $query->page($page, $limit)->select();
            $count = $query->count();

            return json([
                'code' => 200,
                'data' => [
                    'list' => $list,
                    'count' => $count
                ],
                'msg' => '获取成功'
            ]);
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }

    /**
     * 生成车辆二维码
     */
    public function generateQrcode()
    {
        $carNumber = $this->request->param('car_number', '');

        if (empty($carNumber)) {
            return json(['code' => 400, 'msg' => '车牌号不能为空']);
        }

        try {
            // 检查车辆是否存在
            $carInfo = Db::name('sysidcardinfo')
                ->where('CarNomber|IDCardNomber', $carNumber)
                ->find();

            if (!$carInfo || !$carInfo['IDCardNomber']) {
                return json(['code' => 404, 'msg' => '车辆未绑定ID卡']);
            }


            // 注意：这里的 car/detail 页面是小程序的主页面之一，才能在小程序码中作为 scene 使用
            //由于不支持中文只能用  IDCardNomber
            $scene = 'car_number=' . urlencode($carInfo['IDCardNomber']);

            // 生成小程序码
            $qrcodeResult = $this->createWxQrcode($scene, $carInfo['IDCardNomber']);

            if ($qrcodeResult) {
                // 获取应用域名，用于拼接完整URL
                $domain = $this->request->domain();
                return json([
                    'code' => 200,
                    'data' => [
                        'qrcode_url' => $domain . $qrcodeResult,
                        'idcard_number' => $carInfo['IDCardNomber'],
                        'car_number' => $carInfo['CarNomber']
                    ],
                    'msg' => '二维码生成成功'
                ]);
            } else {
                return json(['code' => 500, 'msg' => '二维码生成失败: ' . ($this->lastError ?: '未知错误')]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }

    /**
     * 创建微信小程序码 (新方法)
     * @param string $scene      场景值，最大32个可见字符
     * @param string $filename   保存的文件名
     * @return false|string
     */
    private function createWxQrcode($scene, $filename)
    {
        try {
            $savePath = public_path() . Config::get('applet.qrcode.save_path', 'storage/qrcode/');
            $publicPath = Config::get('applet.qrcode.save_path', 'storage/qrcode/');

            if (!is_dir($savePath)) {
                mkdir($savePath, 0755, true);
            }

            $fileSimpleName = $filename . '.png';
            $fullPath = $savePath . $fileSimpleName;
            $publicFullPath = $publicPath . $fileSimpleName;

            if (file_exists($fullPath)) {
                return $publicFullPath;
            }

            $accessToken = $this->getAccessToken();


            if (!$accessToken) {
                // 可以在这里记录日志：获取 accessToken 失败
                // 直接返回更详细的错误信息
                $this->lastError = '获取 accessToken 失败，请检查 AppID 和 AppSecret 配置以及服务器 IP 白名单。';
                return false;
            }

            $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$accessToken}";
            $postData = json_encode([
                'scene' => $scene,
                'page'  => 'pages/car/detail', // 小程序码跳转的页面
                'check_path' => false // 不检查页面路径，提升容错
            ]);

            $response = $this->curlPost($url, $postData);

            // 检查返回的是否是图片数据
            $responseData = json_decode($response, true);
            if (isset($responseData['errcode'])) {
                // 接口返回错误，可以在这里记录日志 $responseData['errmsg']
                $this->lastError = '小程序码接口返回错误: ' . $responseData['errmsg'] . ' (错误码: ' . $responseData['errcode'] . ')';
                return false;
            }

            // 保存图片文件
            file_put_contents($fullPath, $response);

            if (file_exists($fullPath)) {
                return $publicFullPath;
            }

            return false;
        } catch (\Exception $e) {
            // 记录异常日志 $e->getMessage()
            $this->lastError = '生成二维码时发生异常: ' . $e->getMessage();
            return false;
        }
    }

    /**
     * 获取微信 AccessToken (新方法)
     * @return string|null
     */
    private function getAccessToken()
    {
        $cacheKey = 'wechat_access_token';
        $token = Cache::get($cacheKey);

        if ($token) {
            return $token;
        }

        $appId = Config::get('applet.wechat.app_id');
        $appSecret = Config::get('applet.wechat.app_secret');

        if (empty($appId) || empty($appSecret)) {
            // 记录日志：AppID 或 AppSecret 未配置
            $this->lastError = '小程序 AppID 或 AppSecret 未配置。';
            return null;
        }

        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";

        $response = file_get_contents($url);
        $data = json_decode($response, true);

        if (isset($data['access_token'])) {
            // 缓存 access_token，有效期设置为7000秒，比微信官方的7200秒略短
            Cache::set($cacheKey, $data['access_token'], 7000);
            return $data['access_token'];
        }

        // 记录日志：获取 token 失败, $data['errmsg']
        $this->lastError = '获取 access_token 失败: ' . ($data['errmsg'] ?? '未知错误');
        return null;
    }

    /**
     * cURL POST 请求封装 (新方法)
     */
    private function curlPost($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }


    /**
     * 创建二维码图片 (使用 chillerlan/php-qrcode) - 此方法现在不再直接用于生成小程序码
     * 而是可以作为备用或内部二维码生成器
     */
    private function createQrcode($content, $filename)
    {
        try {
            $savePath = public_path() . Config::get('applet.qrcode.save_path', 'storage/qrcode/');
            $publicPath = Config::get('applet.qrcode.save_path', 'storage/qrcode/');

            // 确保目录存在
            if (!is_dir($savePath)) {
                mkdir($savePath, 0755, true);
            }

            $fileSimpleName = $filename . '.png';
            $fullPath = $savePath . $fileSimpleName;
            $publicFullPath = $publicPath . $fileSimpleName;

            // 如果文件已存在，直接返回公共路径
            if (file_exists($fullPath)) {
                return $publicFullPath;
            }

            // 配置二维码选项
            $options = new QROptions([
                'version'    => 5,
                'outputType' => QRCode::OUTPUT_IMAGE_PNG,
                'eccLevel'   => QRCode::ECC_L,
                'scale'      => 10, // 相当于 300x300px 尺寸
                'imageBase64' => false, // 确保输出的是图像文件而不是base64
            ]);

            // 实例化并生成二维码
            $qrcode = new QRCode($options);
            $qrcode->render($content, $fullPath);

            // 检查文件是否成功创建
            if (file_exists($fullPath)) {
                return $publicFullPath;
            } else {
                return false;
            }
        } catch (\Exception $e) {
            // 可以在这里记录详细错误日志
            // error_log('QR Code generation failed: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * 更新车辆状态
     */
    public function updateCarStatus()
    {
        $carNumber = $this->request->param('car_number', '');
        $status = $this->request->param('status', '');

        if (empty($carNumber) || empty($status)) {
            return json(['code' => 400, 'msg' => '参数不完整']);
        }

        // 检查状态值是否有效
        $validStatus = array_keys(Config::get('applet.car_status', []));
        if (!in_array($status, $validStatus)) {
            return json(['code' => 400, 'msg' => '无效的状态值']);
        }

        try {
            $result = Db::name('syscarinfo')
                ->where('CarNumber', $carNumber)
                ->update(['CarStatus' => $status]);

            if ($result) {
                return json(['code' => 200, 'msg' => '状态更新成功']);
            } else {
                return json(['code' => 404, 'msg' => '车辆不存在或状态未变更']);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => '系统错误：' . $e->getMessage()]);
        }
    }
}
